﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using Microsoft.SharePoint;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.ExceptionManagement;

using SPListNames = Kiiro.Common.Utility.Constants.SPListNames;
using TeamMemberFieldNames = Kiiro.Common.Utility.Constants.TeamMemberFieldNames;

namespace Kiiro.DataAccess
{
    public class TeamDA
    {
        #region Singleton
        private TeamDA ( )
        {
        }

        private static TeamDA instance = null;
        private static readonly object threadLock = new object ( );

        public static TeamDA Instance
        {
            get
            {
                lock ( threadLock )
                {
                    if ( instance == null )
                    {
                        instance = new TeamDA ( );
                    }
                }
                return instance;
            }
        }
        #endregion

        /// <summary>
        /// Gets a list of TeamMember entities. If teamMemberIds param is null or empty this method will returns ALL team members
        /// </summary>
        /// <param name="teamMemberIds">The list of team member ids to get. If teamMemberIds is null or empty this method 
        ///     returns ALL team members.</param>
        /// <param name="siteCollectionId">The site collection id</param>
        /// <param name="serverRelativeUrl">The server relative url</param>
        /// <returns>If teamMemberIds param is null or empty this method will returns ALL team members</returns>
        public List<TeamMember> GetTeamMembersByIds ( List<int> teamMemberIds, Guid siteCollectionId, string serverRelativeUrl )
        {
            List<TeamMember> members = new List<TeamMember> ( );
            SPList list = null;

            try
            {
                using (SPWeb web = SPHelpers.GetWeb(siteCollectionId, serverRelativeUrl))
                {
                    list = web.Lists[SPListNames.TeamMembers];

                    if (list != null)
                    {
                        SPQuery query = new SPQuery();

                        bool first = true;
                        if (teamMemberIds != null)
                        {
                            foreach (int teamMemberId in teamMemberIds)
                            {
                                if (!first) query.Query = "<Or>" + query.Query;
                                query.Query += "<Eq><FieldRef Name='ID'/><Value Type='Integer'>" + teamMemberId + "</Value></Eq>";
                                if (!first) query.Query += "</Or>";

                                first = false;
                            }
                        }

                        if (!string.IsNullOrEmpty(query.Query))
                            query.Query = "<Where>" + query.Query + "</Where>";

                        SPListItemCollection listItems = list.GetItems(query);
                        if (listItems != null && listItems.Count > 0)
                        {
                            foreach (SPListItem listItem in listItems)
                            {
                                try
                                {
                                    members.Add(SPDataHelpers.MakeTeam(listItem));
                                }
                                catch (Exception ex)
                                {
                                    ExceptionManager.HandleException(ex, false);
                                }
                            }
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return members;
        }

        /// <summary>
        /// Gets a list of TeamMember entities
        /// </summary>
        /// <param name="userIds">The list of user ids to get. If userIds is null or empty this method 
        ///     returns ALL team members.</param>
        /// <param name="siteCollectionId">The site collection id</param>
        /// <param name="serverRelativeUrl">The server relative url</param>
        /// <returns>If userIds param is null or empty this method will returns ALL team members</returns>
        public List<TeamMember> GetTeamMembersByUserIds ( List<int> userIds, Guid siteCollectionId, string serverRelativeUrl )
        {
            List<TeamMember> members = new List<TeamMember> ( );
            SPList list = null;

            try
            {
                using (SPWeb web = SPHelpers.GetWeb(siteCollectionId, serverRelativeUrl))
                {
                    list = web.Lists[SPListNames.TeamMembers];

                    if (list != null)
                    {
                        SPQuery query = new SPQuery();

                        bool first = true;
                        if (userIds != null)
                        {
                            foreach (int userId in userIds)
                            {
                                if (!first) query.Query = "<Or>" + query.Query;
                                query.Query += "<Eq><FieldRef Name='" + TeamMemberFieldNames.UserId + "'/><Value Type='Integer'>" + userId + "</Value></Eq>";
                                if (!first) query.Query += "</Or>";

                                first = false;
                            }
                        }

                        if (!string.IsNullOrEmpty(query.Query))
                            query.Query = "<Where>" + query.Query + "</Where>";

                        SPListItemCollection listItems = list.GetItems(query);
                        if (listItems != null && listItems.Count > 0)
                            foreach (SPListItem listItem in listItems)
                                members.Add(SPDataHelpers.MakeTeam(listItem));
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return members;
        }




        public void Save(TeamMember teamMember, Guid siteCollectionId, string serverRelativeUrl)
        {
            SPList list = null;
            SPListItem listItem = null;
            try
            {
                if ( teamMember.EditType != EditType.Unchanged )
                {
                    using (SPWeb web = SPHelpers.GetWeb(siteCollectionId, serverRelativeUrl))
                    {
                        list = web.Lists[Constants.SPListNames.TeamMembers];

                        if (teamMember == null)
                            throw new Exception("Cannot SaveTeamMember() when TeamMember entity is null");

                        if (list != null)
                        {
                            #region Get Item
                            listItem = teamMember.EditType == EditType.Created ? list.Folders.Add() : list.Folders.GetItemById(teamMember.Id);

                            switch (teamMember.EditType)
                            {
                                case EditType.Created:
                                    list.ParentWeb.AllowUnsafeUpdates = true;
                                    listItem.Update();
                                    list.ParentWeb.AllowUnsafeUpdates = false;

                                    listItem = list.Folders.GetItemById(listItem.ID);
                                    listItem[Constants.TeamMemberFieldNames.ServerRelativeUrl] = listItem.Folder.ServerRelativeUrl;
                                    listItem[Constants.TeamMemberFieldNames.SiteCollectionId] = list.ParentWeb.Site.ID;

                                    if (teamMember.CreatedBy != null && teamMember.CreatedBy.Id > 0)
                                        listItem[TeamMemberFieldNames.CreatedBy] = teamMember.CreatedBy.Id;
                                    if (teamMember.CreatedDate != null && teamMember.CreatedDate != DateTime.MinValue)
                                        listItem[TeamMemberFieldNames.CreatedDate] = teamMember.CreatedDate;
                                    if (teamMember.ModifiedBy != null && teamMember.ModifiedBy.Id > 0)
                                        listItem[TeamMemberFieldNames.ModifiedBy] = teamMember.ModifiedBy.Id;
                                    if (teamMember.ModifiedDate != null && teamMember.ModifiedDate != DateTime.MinValue)
                                        listItem[TeamMemberFieldNames.ModifiedDate] = teamMember.ModifiedDate;


                                    break;

                                case EditType.Updated:
                                    if (teamMember.ModifiedBy != null && teamMember.ModifiedBy.Id > 0)
                                        listItem[TeamMemberFieldNames.ModifiedBy] = teamMember.ModifiedBy.Id;
                                    if (teamMember.ModifiedDate != null && teamMember.ModifiedDate != DateTime.MinValue)
                                        listItem[TeamMemberFieldNames.ModifiedDate] = teamMember.ModifiedDate;
                                    break;

                                case EditType.Deleted:
                                default:
                                    break;
                            }
                            #endregion

                            #region Set Item Properties

                            if (listItem != null && teamMember.EditType != EditType.Deleted)
                            {
                                listItem[TeamMemberFieldNames.UserId] = teamMember.UserId;

                                if (!string.IsNullOrEmpty(teamMember.RoleOnProject))
                                    listItem[TeamMemberFieldNames.RoleOnProject] = teamMember.RoleOnProject;
                                else
                                    listItem[TeamMemberFieldNames.RoleOnProject] = string.Empty;

                                listItem[TeamMemberFieldNames.IsProjectManager] = teamMember.IsProjectManager;

                                SPDataHelpers.PopulateCustomFieldsInListItemFromEntity(listItem, teamMember);
                            }
                            #endregion

                            #region Update / Delete Item
                            try
                            {
                                list.ParentWeb.AllowUnsafeUpdates = true;
                                if (teamMember.EditType == EditType.Deleted)
                                {
                                    list.Folders.DeleteItemById(listItem.ID);
                                }
                                else
                                {
                                    listItem.Update();
                                    teamMember = SPDataHelpers.MakeTeam(listItem);
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionManager.HandleException(ex, true);
                            }
                            finally
                            {
                                list.ParentWeb.AllowUnsafeUpdates = false;
                            }
                            #endregion
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.DataAccess/TeamDA.cs $
 * 
 * 9     30/09/09 9:15a Shafia
 * 
 * 8     17/08/09 10:41a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/